package com.goudan.rabbitmq.support;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;

@Slf4j
@Component
public class MessageConfirmCallBack implements RabbitTemplate.ConfirmCallback, RabbitTemplate.ReturnCallback {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @PostConstruct
    public void init() {
        rabbitTemplate.setConfirmCallback(this);
        rabbitTemplate.setReturnCallback(this);
    }

    /**
     * 交换机确认回调方法 (发布者发送消息是否到交换机触发回调)
     * 1. 发消息 交换机接收到消息，回调
     * 1.1 correlationData 保存毁掉消息的id及相关信息
     * 1.2 交换机接收到消息 true
     * 1.3 失败原因-null
     * 2. 发消息 交换机接收失败 回调
     * 2.1 correlationData 保存毁掉消息的id及相关信息
     * 2.2 false
     * 2.3 失败原因
     */
    @Override
    public void confirm(CorrelationData correlationData, boolean ack, String cause) {

        if (ack) {
            log.info("发布确认:交换机收到消息id：{}", correlationData.getId());
        } else {
            log.info("发布确认:交换机未收到消息，id为：{},原因：{}", correlationData.getId(), cause);
        }

    }

    /**
     * 可以将消息传递过程中不可达到目的地(队列)的消息返回给生产者
     * 只有不可达 才会回退消息
     */
    @Override
    public void returnedMessage(Message message, int replyCode, String replyText, String exchange, String routingKey) {
        log.info("消息{}，被交换机{}退回，退回原因：{}，路由Key：{}", new String(message.getBody()), exchange, replyText, routingKey);
    }
}
